{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/peremartra/Large-Language-Model-Notebooks-Course/blob/main/1-Introduction%20to%20LLMs%20with%20OpenAI/Vertical%20Chat.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "<div align=\"center\">\n",
        "<h1><a href=\"https://github.com/peremartra/Large-Language-Model-Notebooks-Course\">Learn by Doing LLM Projects</a></h1>\n",
        "    <h3>Understand And Apply Large Language Models</h3>\n",
        "    <h2>Create your first ChatBot with OpenAI</h2>\n",
        "    <h3>Using GPT 3.5, Python and Panel</h3>\n",
        "    by <b>Pere Martra</b>\n",
        "</div>\n",
        "\n",
        "<br>\n",
        "\n",
        "<div align=\"center\">\n",
        "    &nbsp;\n",
        "    <a target=\"_blank\" href=\"https://www.linkedin.com/in/pere-martra/\"><img src=\"https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social\"></a>\n",
        "    \n",
        "</div>\n",
        "\n",
        "<br>\n",
        "<hr>"
      ],
      "metadata": {
        "id": "zwzWskLgXgj5"
      },
      "id": "zwzWskLgXgj5"
    },
    {
      "cell_type": "markdown",
      "id": "c23b4dd1",
      "metadata": {
        "id": "c23b4dd1"
      },
      "source": [
        "# Vertical Chat\n",
        "A sample how to build a chat for small businees using:\n",
        "\n",
        "* GPT 35\n",
        "* Panel\n",
        "* OpenAI\n",
        "\n",
        "\n",
        "This is just a simple sample to start to understand how the OpenAI API works, and how to create Prompts. It Is really far from beign a complete solution.\n",
        "We are going to introduce some interesting points:\n",
        "\n",
        "* The roles in a conversation.\n",
        "* How is the conversations’ memory preserved?\n",
        "\n",
        "Deeper explanations in the article: [Create Your First Chatbot Using GPT 3.5, OpenAI, Python and Panel.](https://medium.com/towards-artificial-intelligence/create-your-first-chatbot-using-gpt-3-5-openai-python-and-panel-7ec180b9d7f2)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "a1d00720",
      "metadata": {
        "id": "a1d00720",
        "outputId": "507ec869-bd20-4837-e731-4188221494dd",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Collecting openai==1.1.1\n",
            "  Downloading openai-1.1.1-py3-none-any.whl (217 kB)\n",
            "\u001b[?25l     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/217.8 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K     \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[90m╺\u001b[0m \u001b[32m215.0/217.8 kB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m217.8/217.8 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hRequirement already satisfied: anyio<4,>=3.5.0 in /usr/local/lib/python3.10/dist-packages (from openai==1.1.1) (3.7.1)\n",
            "Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai==1.1.1) (1.7.0)\n",
            "Collecting httpx<1,>=0.23.0 (from openai==1.1.1)\n",
            "  Downloading httpx-0.25.1-py3-none-any.whl (75 kB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.0/75.0 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hRequirement already satisfied: pydantic<3,>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from openai==1.1.1) (1.10.13)\n",
            "Requirement already satisfied: tqdm>4 in /usr/local/lib/python3.10/dist-packages (from openai==1.1.1) (4.66.1)\n",
            "Requirement already satisfied: typing-extensions<5,>=4.5 in /usr/local/lib/python3.10/dist-packages (from openai==1.1.1) (4.5.0)\n",
            "Requirement already satisfied: idna>=2.8 in /usr/local/lib/python3.10/dist-packages (from anyio<4,>=3.5.0->openai==1.1.1) (3.4)\n",
            "Requirement already satisfied: sniffio>=1.1 in /usr/local/lib/python3.10/dist-packages (from anyio<4,>=3.5.0->openai==1.1.1) (1.3.0)\n",
            "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<4,>=3.5.0->openai==1.1.1) (1.1.3)\n",
            "Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from httpx<1,>=0.23.0->openai==1.1.1) (2023.7.22)\n",
            "Collecting httpcore (from httpx<1,>=0.23.0->openai==1.1.1)\n",
            "  Downloading httpcore-1.0.1-py3-none-any.whl (76 kB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.9/76.9 kB\u001b[0m \u001b[31m8.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hCollecting h11<0.15,>=0.13 (from httpcore->httpx<1,>=0.23.0->openai==1.1.1)\n",
            "  Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hInstalling collected packages: h11, httpcore, httpx, openai\n",
            "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "llmx 0.0.15a0 requires cohere, which is not installed.\n",
            "llmx 0.0.15a0 requires tiktoken, which is not installed.\u001b[0m\u001b[31m\n",
            "\u001b[0mSuccessfully installed h11-0.14.0 httpcore-1.0.1 httpx-0.25.1 openai-1.1.1\n",
            "Requirement already satisfied: panel in /usr/local/lib/python3.10/dist-packages (1.3.1)\n",
            "Requirement already satisfied: bokeh<3.4.0,>=3.2.0 in /usr/local/lib/python3.10/dist-packages (from panel) (3.3.0)\n",
            "Requirement already satisfied: param<3.0,>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from panel) (2.0.0)\n",
            "Requirement already satisfied: pyviz-comms>=0.7.4 in /usr/local/lib/python3.10/dist-packages (from panel) (3.0.0)\n",
            "Requirement already satisfied: xyzservices>=2021.09.1 in /usr/local/lib/python3.10/dist-packages (from panel) (2023.10.1)\n",
            "Requirement already satisfied: markdown in /usr/local/lib/python3.10/dist-packages (from panel) (3.5.1)\n",
            "Requirement already satisfied: markdown-it-py in /usr/local/lib/python3.10/dist-packages (from panel) (3.0.0)\n",
            "Requirement already satisfied: linkify-it-py in /usr/local/lib/python3.10/dist-packages (from panel) (2.0.2)\n",
            "Requirement already satisfied: mdit-py-plugins in /usr/local/lib/python3.10/dist-packages (from panel) (0.4.0)\n",
            "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from panel) (2.31.0)\n",
            "Requirement already satisfied: tqdm>=4.48.0 in /usr/local/lib/python3.10/dist-packages (from panel) (4.66.1)\n",
            "Requirement already satisfied: bleach in /usr/local/lib/python3.10/dist-packages (from panel) (6.1.0)\n",
            "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from panel) (4.5.0)\n",
            "Requirement already satisfied: pandas>=1.2 in /usr/local/lib/python3.10/dist-packages (from panel) (1.5.3)\n",
            "Requirement already satisfied: Jinja2>=2.9 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (3.1.2)\n",
            "Requirement already satisfied: contourpy>=1 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (1.2.0)\n",
            "Requirement already satisfied: numpy>=1.16 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (1.23.5)\n",
            "Requirement already satisfied: packaging>=16.8 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (23.2)\n",
            "Requirement already satisfied: pillow>=7.1.0 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (9.4.0)\n",
            "Requirement already satisfied: PyYAML>=3.10 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (6.0.1)\n",
            "Requirement already satisfied: tornado>=5.1 in /usr/local/lib/python3.10/dist-packages (from bokeh<3.4.0,>=3.2.0->panel) (6.3.2)\n",
            "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.2->panel) (2.8.2)\n",
            "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.2->panel) (2023.3.post1)\n",
            "Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from bleach->panel) (1.16.0)\n",
            "Requirement already satisfied: webencodings in /usr/local/lib/python3.10/dist-packages (from bleach->panel) (0.5.1)\n",
            "Requirement already satisfied: uc-micro-py in /usr/local/lib/python3.10/dist-packages (from linkify-it-py->panel) (1.0.2)\n",
            "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py->panel) (0.1.2)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->panel) (3.3.2)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->panel) (3.4)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->panel) (2.0.7)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->panel) (2023.7.22)\n",
            "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from Jinja2>=2.9->bokeh<3.4.0,>=3.2.0->panel) (2.1.3)\n"
          ]
        }
      ],
      "source": [
        "#First install the necesary libraries\n",
        "!pip install openai==1.1.1\n",
        "!pip install panel"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "a03f026a",
      "metadata": {
        "id": "a03f026a"
      },
      "outputs": [],
      "source": [
        "#if you need a API Key from OpenAI\n",
        "#https://platform.openai.com/account/api-keys\n",
        "\n",
        "import openai\n",
        "import panel as pn\n",
        "#from mykeys import openai_api_key\n",
        "openai.api_key=\"your-api-key\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "77eac86d",
      "metadata": {
        "id": "77eac86d"
      },
      "outputs": [],
      "source": [
        "def continue_conversation(messages, temperature=0):\n",
        "    response = openai.chat.completions.create(\n",
        "        model=\"gpt-3.5-turbo\",\n",
        "        messages=messages,\n",
        "        temperature=temperature,\n",
        "    )\n",
        "    #print(str(response.choices[0].message[\"content\"]))\n",
        "    return response.choices[0].message.content"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "51bec475",
      "metadata": {
        "id": "51bec475"
      },
      "outputs": [],
      "source": [
        "def add_prompts_conversation(_):\n",
        "    #Get the value introduced by the user\n",
        "    prompt = client_prompt.value_input\n",
        "    client_prompt.value = ''\n",
        "\n",
        "    #Append to the context the User promnopt.\n",
        "    context.append({'role':'user', 'content':f\"{prompt}\"})\n",
        "\n",
        "    #Get the response.\n",
        "    response = continue_conversation(context)\n",
        "\n",
        "    #Add the response to the context.\n",
        "    context.append({'role':'assistant', 'content':f\"{response}\"})\n",
        "\n",
        "    #Undate the panels to shjow the conversation.\n",
        "    panels.append(\n",
        "        pn.Row('User:', pn.pane.Markdown(prompt, width=600)))\n",
        "    panels.append(\n",
        "        pn.Row('Assistant:', pn.pane.Markdown(response, width=600)))\n",
        "\n",
        "    return pn.Column(*panels)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "922f8d24",
      "metadata": {
        "id": "922f8d24",
        "outputId": "93183987-3b29-4430-d8cc-6d6453a98574",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 573
        }
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "application/javascript": [
              "(function(root) {\n",
              "  function now() {\n",
              "    return new Date();\n",
              "  }\n",
              "\n",
              "  var force = true;\n",
              "  var py_version = '3.3.0'.replace('rc', '-rc.').replace('.dev', '-dev.');\n",
              "  var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n",
              "  var reloading = false;\n",
              "  var Bokeh = root.Bokeh;\n",
              "  var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n",
              "\n",
              "  if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n",
              "    root._bokeh_timeout = Date.now() + 5000;\n",
              "    root._bokeh_failed_load = false;\n",
              "  }\n",
              "\n",
              "  function run_callbacks() {\n",
              "    try {\n",
              "      root._bokeh_onload_callbacks.forEach(function(callback) {\n",
              "        if (callback != null)\n",
              "          callback();\n",
              "      });\n",
              "    } finally {\n",
              "      delete root._bokeh_onload_callbacks;\n",
              "    }\n",
              "    console.debug(\"Bokeh: all callbacks have finished\");\n",
              "  }\n",
              "\n",
              "  function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n",
              "    if (css_urls == null) css_urls = [];\n",
              "    if (js_urls == null) js_urls = [];\n",
              "    if (js_modules == null) js_modules = [];\n",
              "    if (js_exports == null) js_exports = {};\n",
              "\n",
              "    root._bokeh_onload_callbacks.push(callback);\n",
              "\n",
              "    if (root._bokeh_is_loading > 0) {\n",
              "      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
              "      return null;\n",
              "    }\n",
              "    if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n",
              "      run_callbacks();\n",
              "      return null;\n",
              "    }\n",
              "    if (!reloading) {\n",
              "      console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
              "    }\n",
              "\n",
              "    function on_load() {\n",
              "      root._bokeh_is_loading--;\n",
              "      if (root._bokeh_is_loading === 0) {\n",
              "        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n",
              "        run_callbacks()\n",
              "      }\n",
              "    }\n",
              "    window._bokeh_on_load = on_load\n",
              "\n",
              "    function on_error() {\n",
              "      console.error(\"failed to load \" + url);\n",
              "    }\n",
              "\n",
              "    var skip = [];\n",
              "    if (window.requirejs) {\n",
              "      window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n",
              "      require([\"jspanel\"], function(jsPanel) {\n",
              "\twindow.jsPanel = jsPanel\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-modal\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-tooltip\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-hint\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-layout\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-contextmenu\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-dock\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"gridstack\"], function(GridStack) {\n",
              "\twindow.GridStack = GridStack\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"notyf\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      root._bokeh_is_loading = css_urls.length + 9;\n",
              "    } else {\n",
              "      root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n",
              "    }\n",
              "\n",
              "    var existing_stylesheets = []\n",
              "    var links = document.getElementsByTagName('link')\n",
              "    for (var i = 0; i < links.length; i++) {\n",
              "      var link = links[i]\n",
              "      if (link.href != null) {\n",
              "\texisting_stylesheets.push(link.href)\n",
              "      }\n",
              "    }\n",
              "    for (var i = 0; i < css_urls.length; i++) {\n",
              "      var url = css_urls[i];\n",
              "      if (existing_stylesheets.indexOf(url) !== -1) {\n",
              "\ton_load()\n",
              "\tcontinue;\n",
              "      }\n",
              "      const element = document.createElement(\"link\");\n",
              "      element.onload = on_load;\n",
              "      element.onerror = on_error;\n",
              "      element.rel = \"stylesheet\";\n",
              "      element.type = \"text/css\";\n",
              "      element.href = url;\n",
              "      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n",
              "      document.body.appendChild(element);\n",
              "    }    if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n",
              "      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n",
              "      for (var i = 0; i < urls.length; i++) {\n",
              "        skip.push(urls[i])\n",
              "      }\n",
              "    }    if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n",
              "      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n",
              "      for (var i = 0; i < urls.length; i++) {\n",
              "        skip.push(urls[i])\n",
              "      }\n",
              "    }    if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n",
              "      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n",
              "      for (var i = 0; i < urls.length; i++) {\n",
              "        skip.push(urls[i])\n",
              "      }\n",
              "    }    var existing_scripts = []\n",
              "    var scripts = document.getElementsByTagName('script')\n",
              "    for (var i = 0; i < scripts.length; i++) {\n",
              "      var script = scripts[i]\n",
              "      if (script.src != null) {\n",
              "\texisting_scripts.push(script.src)\n",
              "      }\n",
              "    }\n",
              "    for (var i = 0; i < js_urls.length; i++) {\n",
              "      var url = js_urls[i];\n",
              "      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n",
              "\tif (!window.requirejs) {\n",
              "\t  on_load();\n",
              "\t}\n",
              "\tcontinue;\n",
              "      }\n",
              "      var element = document.createElement('script');\n",
              "      element.onload = on_load;\n",
              "      element.onerror = on_error;\n",
              "      element.async = false;\n",
              "      element.src = url;\n",
              "      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
              "      document.head.appendChild(element);\n",
              "    }\n",
              "    for (var i = 0; i < js_modules.length; i++) {\n",
              "      var url = js_modules[i];\n",
              "      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n",
              "\tif (!window.requirejs) {\n",
              "\t  on_load();\n",
              "\t}\n",
              "\tcontinue;\n",
              "      }\n",
              "      var element = document.createElement('script');\n",
              "      element.onload = on_load;\n",
              "      element.onerror = on_error;\n",
              "      element.async = false;\n",
              "      element.src = url;\n",
              "      element.type = \"module\";\n",
              "      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
              "      document.head.appendChild(element);\n",
              "    }\n",
              "    for (const name in js_exports) {\n",
              "      var url = js_exports[name];\n",
              "      if (skip.indexOf(url) >= 0 || root[name] != null) {\n",
              "\tif (!window.requirejs) {\n",
              "\t  on_load();\n",
              "\t}\n",
              "\tcontinue;\n",
              "      }\n",
              "      var element = document.createElement('script');\n",
              "      element.onerror = on_error;\n",
              "      element.async = false;\n",
              "      element.type = \"module\";\n",
              "      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
              "      element.textContent = `\n",
              "      import ${name} from \"${url}\"\n",
              "      window.${name} = ${name}\n",
              "      window._bokeh_on_load()\n",
              "      `\n",
              "      document.head.appendChild(element);\n",
              "    }\n",
              "    if (!js_urls.length && !js_modules.length) {\n",
              "      on_load()\n",
              "    }\n",
              "  };\n",
              "\n",
              "  function inject_raw_css(css) {\n",
              "    const element = document.createElement(\"style\");\n",
              "    element.appendChild(document.createTextNode(css));\n",
              "    document.body.appendChild(element);\n",
              "  }\n",
              "\n",
              "  var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.0.min.js\", \"https://cdn.holoviz.org/panel/1.3.1/dist/panel.min.js\"];\n",
              "  var js_modules = [];\n",
              "  var js_exports = {};\n",
              "  var css_urls = [];\n",
              "  var inline_js = [    function(Bokeh) {\n",
              "      Bokeh.set_log_level(\"info\");\n",
              "    },\n",
              "function(Bokeh) {} // ensure no trailing comma for IE\n",
              "  ];\n",
              "\n",
              "  function run_inline_js() {\n",
              "    if ((root.Bokeh !== undefined) || (force === true)) {\n",
              "      for (var i = 0; i < inline_js.length; i++) {\n",
              "        inline_js[i].call(root, root.Bokeh);\n",
              "      }\n",
              "      // Cache old bokeh versions\n",
              "      if (Bokeh != undefined && !reloading) {\n",
              "\tvar NewBokeh = root.Bokeh;\n",
              "\tif (Bokeh.versions === undefined) {\n",
              "\t  Bokeh.versions = new Map();\n",
              "\t}\n",
              "\tif (NewBokeh.version !== Bokeh.version) {\n",
              "\t  Bokeh.versions.set(NewBokeh.version, NewBokeh)\n",
              "\t}\n",
              "\troot.Bokeh = Bokeh;\n",
              "      }} else if (Date.now() < root._bokeh_timeout) {\n",
              "      setTimeout(run_inline_js, 100);\n",
              "    } else if (!root._bokeh_failed_load) {\n",
              "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
              "      root._bokeh_failed_load = true;\n",
              "    }\n",
              "    root._bokeh_is_initializing = false\n",
              "  }\n",
              "\n",
              "  function load_or_wait() {\n",
              "    // Implement a backoff loop that tries to ensure we do not load multiple\n",
              "    // versions of Bokeh and its dependencies at the same time.\n",
              "    // In recent versions we use the root._bokeh_is_initializing flag\n",
              "    // to determine whether there is an ongoing attempt to initialize\n",
              "    // bokeh, however for backward compatibility we also try to ensure\n",
              "    // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n",
              "    // before older versions are fully initialized.\n",
              "    if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n",
              "      root._bokeh_is_initializing = false;\n",
              "      root._bokeh_onload_callbacks = undefined;\n",
              "      console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n",
              "      load_or_wait();\n",
              "    } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n",
              "      setTimeout(load_or_wait, 100);\n",
              "    } else {\n",
              "      Bokeh = root.Bokeh;\n",
              "      bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n",
              "      root._bokeh_is_initializing = true\n",
              "      root._bokeh_onload_callbacks = []\n",
              "      if (!reloading && (!bokeh_loaded || is_dev)) {\n",
              "\troot.Bokeh = undefined;\n",
              "      }\n",
              "      load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n",
              "\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n",
              "\trun_inline_js();\n",
              "      });\n",
              "    }\n",
              "  }\n",
              "  // Give older versions of the autoload script a head-start to ensure\n",
              "  // they initialize before we start loading newer version.\n",
              "  setTimeout(load_or_wait, 100)\n",
              "}(window));"
            ],
            "application/vnd.holoviews_load.v0+json": "(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  var force = true;\n  var py_version = '3.3.0'.replace('rc', '-rc.').replace('.dev', '-dev.');\n  var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n  var reloading = false;\n  var Bokeh = root.Bokeh;\n  var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n  if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) {\n        if (callback != null)\n          callback();\n      });\n    } finally {\n      delete root._bokeh_onload_callbacks;\n    }\n    console.debug(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n    if (css_urls == null) css_urls = [];\n    if (js_urls == null) js_urls = [];\n    if (js_modules == null) js_modules = [];\n    if (js_exports == null) js_exports = {};\n\n    root._bokeh_onload_callbacks.push(callback);\n\n    if (root._bokeh_is_loading > 0) {\n      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n      run_callbacks();\n      return null;\n    }\n    if (!reloading) {\n      console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    }\n\n    function on_load() {\n      root._bokeh_is_loading--;\n      if (root._bokeh_is_loading === 0) {\n        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n        run_callbacks()\n      }\n    }\n    window._bokeh_on_load = on_load\n\n    function on_error() {\n      console.error(\"failed to load \" + url);\n    }\n\n    var skip = [];\n    if (window.requirejs) {\n      window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n      require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n      })\n      require([\"jspanel-modal\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-tooltip\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-hint\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-layout\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-dock\"], function() {\n\ton_load()\n      })\n      require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n      })\n      require([\"notyf\"], function() {\n\ton_load()\n      })\n      root._bokeh_is_loading = css_urls.length + 9;\n    } else {\n      root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n    }\n\n    var existing_stylesheets = []\n    var links = document.getElementsByTagName('link')\n    for (var i = 0; i < links.length; i++) {\n      var link = links[i]\n      if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n      }\n    }\n    for (var i = 0; i < css_urls.length; i++) {\n      var url = css_urls[i];\n      if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n      }\n      const element = document.createElement(\"link\");\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.rel = \"stylesheet\";\n      element.type = \"text/css\";\n      element.href = url;\n      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n      document.body.appendChild(element);\n    }    if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(urls[i])\n      }\n    }    if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(urls[i])\n      }\n    }    if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(urls[i])\n      }\n    }    var existing_scripts = []\n    var scripts = document.getElementsByTagName('script')\n    for (var i = 0; i < scripts.length; i++) {\n      var script = scripts[i]\n      if (script.src != null) {\n\texisting_scripts.push(script.src)\n      }\n    }\n    for (var i = 0; i < js_urls.length; i++) {\n      var url = js_urls[i];\n      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t  on_load();\n\t}\n\tcontinue;\n      }\n      var element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (var i = 0; i < js_modules.length; i++) {\n      var url = js_modules[i];\n      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t  on_load();\n\t}\n\tcontinue;\n      }\n      var element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (const name in js_exports) {\n      var url = js_exports[name];\n      if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t  on_load();\n\t}\n\tcontinue;\n      }\n      var element = document.createElement('script');\n      element.onerror = on_error;\n      element.async = false;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      element.textContent = `\n      import ${name} from \"${url}\"\n      window.${name} = ${name}\n      window._bokeh_on_load()\n      `\n      document.head.appendChild(element);\n    }\n    if (!js_urls.length && !js_modules.length) {\n      on_load()\n    }\n  };\n\n  function inject_raw_css(css) {\n    const element = document.createElement(\"style\");\n    element.appendChild(document.createTextNode(css));\n    document.body.appendChild(element);\n  }\n\n  var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.0.min.js\", \"https://cdn.holoviz.org/panel/1.3.1/dist/panel.min.js\"];\n  var js_modules = [];\n  var js_exports = {};\n  var css_urls = [];\n  var inline_js = [    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n  ];\n\n  function run_inline_js() {\n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (var i = 0; i < inline_js.length; i++) {\n        inline_js[i].call(root, root.Bokeh);\n      }\n      // Cache old bokeh versions\n      if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t  Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t  Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    }\n    root._bokeh_is_initializing = false\n  }\n\n  function load_or_wait() {\n    // Implement a backoff loop that tries to ensure we do not load multiple\n    // versions of Bokeh and its dependencies at the same time.\n    // In recent versions we use the root._bokeh_is_initializing flag\n    // to determine whether there is an ongoing attempt to initialize\n    // bokeh, however for backward compatibility we also try to ensure\n    // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n    // before older versions are fully initialized.\n    if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n      root._bokeh_is_initializing = false;\n      root._bokeh_onload_callbacks = undefined;\n      console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n      load_or_wait();\n    } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n      setTimeout(load_or_wait, 100);\n    } else {\n      Bokeh = root.Bokeh;\n      bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n      root._bokeh_is_initializing = true\n      root._bokeh_onload_callbacks = []\n      if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n      }\n      load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n      });\n    }\n  }\n  // Give older versions of the autoload script a head-start to ensure\n  // they initialize before we start loading newer version.\n  setTimeout(load_or_wait, 100)\n}(window));"
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n  window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n    function JupyterCommManager() {\n    }\n\n    JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n      if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        comm_manager.register_target(comm_id, function(comm) {\n          comm.on_msg(msg_handler);\n        });\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n          comm.onMsg = msg_handler;\n        });\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n          var messages = comm.messages[Symbol.asyncIterator]();\n          function processIteratorResult(result) {\n            var message = result.value;\n            console.log(message)\n            var content = {data: message.data, comm_id};\n            var buffers = []\n            for (var buffer of message.buffers || []) {\n              buffers.push(new DataView(buffer))\n            }\n            var metadata = message.metadata || {};\n            var msg = {content, buffers, metadata}\n            msg_handler(msg);\n            return messages.next().then(processIteratorResult);\n          }\n          return messages.next().then(processIteratorResult);\n        })\n      }\n    }\n\n    JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n      if (comm_id in window.PyViz.comms) {\n        return window.PyViz.comms[comm_id];\n      } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n        if (msg_handler) {\n          comm.on_msg(msg_handler);\n        }\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n        comm.open();\n        if (msg_handler) {\n          comm.onMsg = msg_handler;\n        }\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        var comm_promise = google.colab.kernel.comms.open(comm_id)\n        comm_promise.then((comm) => {\n          window.PyViz.comms[comm_id] = comm;\n          if (msg_handler) {\n            var messages = comm.messages[Symbol.asyncIterator]();\n            function processIteratorResult(result) {\n              var message = result.value;\n              var content = {data: message.data};\n              var metadata = message.metadata || {comm_id};\n              var msg = {content, metadata}\n              msg_handler(msg);\n              return messages.next().then(processIteratorResult);\n            }\n            return messages.next().then(processIteratorResult);\n          }\n        }) \n        var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n          return comm_promise.then((comm) => {\n            comm.send(data, metadata, buffers, disposeOnDone);\n          });\n        };\n        var comm = {\n          send: sendClosure\n        };\n      }\n      window.PyViz.comms[comm_id] = comm;\n      return comm;\n    }\n    window.PyViz.comm_manager = new JupyterCommManager();\n    \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n  var div = document.createElement(\"div\");\n  var script = document.createElement(\"script\");\n  node.appendChild(div);\n  node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n  var output_area = handle.output_area;\n  var output = handle.output;\n  if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n    return\n  }\n  var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n  var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n  if (id !== undefined) {\n    var nchildren = toinsert.length;\n    var html_node = toinsert[nchildren-1].children[0];\n    html_node.innerHTML = output.data[HTML_MIME_TYPE];\n    var scripts = [];\n    var nodelist = html_node.querySelectorAll(\"script\");\n    for (var i in nodelist) {\n      if (nodelist.hasOwnProperty(i)) {\n        scripts.push(nodelist[i])\n      }\n    }\n\n    scripts.forEach( function (oldScript) {\n      var newScript = document.createElement(\"script\");\n      var attrs = [];\n      var nodemap = oldScript.attributes;\n      for (var j in nodemap) {\n        if (nodemap.hasOwnProperty(j)) {\n          attrs.push(nodemap[j])\n        }\n      }\n      attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n      newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n      oldScript.parentNode.replaceChild(newScript, oldScript);\n    });\n    if (JS_MIME_TYPE in output.data) {\n      toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n    }\n    output_area._hv_plot_id = id;\n    if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n      window.PyViz.plot_index[id] = Bokeh.index[id];\n    } else {\n      window.PyViz.plot_index[id] = null;\n    }\n  } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n    var bk_div = document.createElement(\"div\");\n    bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n    var script_attrs = bk_div.children[0].attributes;\n    for (var i = 0; i < script_attrs.length; i++) {\n      toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n    }\n    // store reference to server id on output_area\n    output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n  }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n  var id = handle.cell.output_area._hv_plot_id;\n  var server_id = handle.cell.output_area._bokeh_server_id;\n  if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n  var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n  if (server_id !== null) {\n    comm.send({event_type: 'server_delete', 'id': server_id});\n    return;\n  } else if (comm !== null) {\n    comm.send({event_type: 'delete', 'id': id});\n  }\n  delete PyViz.plot_index[id];\n  if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n    var doc = window.Bokeh.index[id].model.document\n    doc.clear();\n    const i = window.Bokeh.documents.indexOf(doc);\n    if (i > -1) {\n      window.Bokeh.documents.splice(i, 1);\n    }\n  }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n  delete PyViz.comms[\"hv-extension-comm\"];\n  window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n  handle_clear_output(event, {cell: {output_area: handle.output_area}})\n  handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n  function append_mime(data, metadata, element) {\n    // create a DOM node to render to\n    var toinsert = this.create_output_subarea(\n    metadata,\n    CLASS_NAME,\n    EXEC_MIME_TYPE\n    );\n    this.keyboard_manager.register_events(toinsert);\n    // Render to node\n    var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n    render(props, toinsert[0]);\n    element.append(toinsert);\n    return toinsert\n  }\n\n  events.on('output_added.OutputArea', handle_add_output);\n  events.on('output_updated.OutputArea', handle_update_output);\n  events.on('clear_output.CodeCell', handle_clear_output);\n  events.on('delete.Cell', handle_clear_output);\n  events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n  OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n    safe: true,\n    index: 0\n  });\n}\n\nif (window.Jupyter !== undefined) {\n  try {\n    var events = require('base/js/events');\n    var OutputArea = require('notebook/js/outputarea').OutputArea;\n    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n      register_renderer(events, OutputArea);\n    }\n  } catch(err) {\n  }\n}\n",
            "application/javascript": [
              "\n",
              "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n",
              "  window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n",
              "}\n",
              "\n",
              "\n",
              "    function JupyterCommManager() {\n",
              "    }\n",
              "\n",
              "    JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n",
              "      if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
              "        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
              "        comm_manager.register_target(comm_id, function(comm) {\n",
              "          comm.on_msg(msg_handler);\n",
              "        });\n",
              "      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
              "        window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n",
              "          comm.onMsg = msg_handler;\n",
              "        });\n",
              "      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
              "        google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n",
              "          var messages = comm.messages[Symbol.asyncIterator]();\n",
              "          function processIteratorResult(result) {\n",
              "            var message = result.value;\n",
              "            console.log(message)\n",
              "            var content = {data: message.data, comm_id};\n",
              "            var buffers = []\n",
              "            for (var buffer of message.buffers || []) {\n",
              "              buffers.push(new DataView(buffer))\n",
              "            }\n",
              "            var metadata = message.metadata || {};\n",
              "            var msg = {content, buffers, metadata}\n",
              "            msg_handler(msg);\n",
              "            return messages.next().then(processIteratorResult);\n",
              "          }\n",
              "          return messages.next().then(processIteratorResult);\n",
              "        })\n",
              "      }\n",
              "    }\n",
              "\n",
              "    JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n",
              "      if (comm_id in window.PyViz.comms) {\n",
              "        return window.PyViz.comms[comm_id];\n",
              "      } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
              "        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
              "        var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n",
              "        if (msg_handler) {\n",
              "          comm.on_msg(msg_handler);\n",
              "        }\n",
              "      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
              "        var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n",
              "        comm.open();\n",
              "        if (msg_handler) {\n",
              "          comm.onMsg = msg_handler;\n",
              "        }\n",
              "      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
              "        var comm_promise = google.colab.kernel.comms.open(comm_id)\n",
              "        comm_promise.then((comm) => {\n",
              "          window.PyViz.comms[comm_id] = comm;\n",
              "          if (msg_handler) {\n",
              "            var messages = comm.messages[Symbol.asyncIterator]();\n",
              "            function processIteratorResult(result) {\n",
              "              var message = result.value;\n",
              "              var content = {data: message.data};\n",
              "              var metadata = message.metadata || {comm_id};\n",
              "              var msg = {content, metadata}\n",
              "              msg_handler(msg);\n",
              "              return messages.next().then(processIteratorResult);\n",
              "            }\n",
              "            return messages.next().then(processIteratorResult);\n",
              "          }\n",
              "        }) \n",
              "        var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n",
              "          return comm_promise.then((comm) => {\n",
              "            comm.send(data, metadata, buffers, disposeOnDone);\n",
              "          });\n",
              "        };\n",
              "        var comm = {\n",
              "          send: sendClosure\n",
              "        };\n",
              "      }\n",
              "      window.PyViz.comms[comm_id] = comm;\n",
              "      return comm;\n",
              "    }\n",
              "    window.PyViz.comm_manager = new JupyterCommManager();\n",
              "    \n",
              "\n",
              "\n",
              "var JS_MIME_TYPE = 'application/javascript';\n",
              "var HTML_MIME_TYPE = 'text/html';\n",
              "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n",
              "var CLASS_NAME = 'output';\n",
              "\n",
              "/**\n",
              " * Render data to the DOM node\n",
              " */\n",
              "function render(props, node) {\n",
              "  var div = document.createElement(\"div\");\n",
              "  var script = document.createElement(\"script\");\n",
              "  node.appendChild(div);\n",
              "  node.appendChild(script);\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle when a new output is added\n",
              " */\n",
              "function handle_add_output(event, handle) {\n",
              "  var output_area = handle.output_area;\n",
              "  var output = handle.output;\n",
              "  if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
              "    return\n",
              "  }\n",
              "  var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
              "  var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
              "  if (id !== undefined) {\n",
              "    var nchildren = toinsert.length;\n",
              "    var html_node = toinsert[nchildren-1].children[0];\n",
              "    html_node.innerHTML = output.data[HTML_MIME_TYPE];\n",
              "    var scripts = [];\n",
              "    var nodelist = html_node.querySelectorAll(\"script\");\n",
              "    for (var i in nodelist) {\n",
              "      if (nodelist.hasOwnProperty(i)) {\n",
              "        scripts.push(nodelist[i])\n",
              "      }\n",
              "    }\n",
              "\n",
              "    scripts.forEach( function (oldScript) {\n",
              "      var newScript = document.createElement(\"script\");\n",
              "      var attrs = [];\n",
              "      var nodemap = oldScript.attributes;\n",
              "      for (var j in nodemap) {\n",
              "        if (nodemap.hasOwnProperty(j)) {\n",
              "          attrs.push(nodemap[j])\n",
              "        }\n",
              "      }\n",
              "      attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n",
              "      newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n",
              "      oldScript.parentNode.replaceChild(newScript, oldScript);\n",
              "    });\n",
              "    if (JS_MIME_TYPE in output.data) {\n",
              "      toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n",
              "    }\n",
              "    output_area._hv_plot_id = id;\n",
              "    if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n",
              "      window.PyViz.plot_index[id] = Bokeh.index[id];\n",
              "    } else {\n",
              "      window.PyViz.plot_index[id] = null;\n",
              "    }\n",
              "  } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
              "    var bk_div = document.createElement(\"div\");\n",
              "    bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
              "    var script_attrs = bk_div.children[0].attributes;\n",
              "    for (var i = 0; i < script_attrs.length; i++) {\n",
              "      toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
              "    }\n",
              "    // store reference to server id on output_area\n",
              "    output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
              "  }\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle when an output is cleared or removed\n",
              " */\n",
              "function handle_clear_output(event, handle) {\n",
              "  var id = handle.cell.output_area._hv_plot_id;\n",
              "  var server_id = handle.cell.output_area._bokeh_server_id;\n",
              "  if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n",
              "  var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n",
              "  if (server_id !== null) {\n",
              "    comm.send({event_type: 'server_delete', 'id': server_id});\n",
              "    return;\n",
              "  } else if (comm !== null) {\n",
              "    comm.send({event_type: 'delete', 'id': id});\n",
              "  }\n",
              "  delete PyViz.plot_index[id];\n",
              "  if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n",
              "    var doc = window.Bokeh.index[id].model.document\n",
              "    doc.clear();\n",
              "    const i = window.Bokeh.documents.indexOf(doc);\n",
              "    if (i > -1) {\n",
              "      window.Bokeh.documents.splice(i, 1);\n",
              "    }\n",
              "  }\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle kernel restart event\n",
              " */\n",
              "function handle_kernel_cleanup(event, handle) {\n",
              "  delete PyViz.comms[\"hv-extension-comm\"];\n",
              "  window.PyViz.plot_index = {}\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle update_display_data messages\n",
              " */\n",
              "function handle_update_output(event, handle) {\n",
              "  handle_clear_output(event, {cell: {output_area: handle.output_area}})\n",
              "  handle_add_output(event, handle)\n",
              "}\n",
              "\n",
              "function register_renderer(events, OutputArea) {\n",
              "  function append_mime(data, metadata, element) {\n",
              "    // create a DOM node to render to\n",
              "    var toinsert = this.create_output_subarea(\n",
              "    metadata,\n",
              "    CLASS_NAME,\n",
              "    EXEC_MIME_TYPE\n",
              "    );\n",
              "    this.keyboard_manager.register_events(toinsert);\n",
              "    // Render to node\n",
              "    var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
              "    render(props, toinsert[0]);\n",
              "    element.append(toinsert);\n",
              "    return toinsert\n",
              "  }\n",
              "\n",
              "  events.on('output_added.OutputArea', handle_add_output);\n",
              "  events.on('output_updated.OutputArea', handle_update_output);\n",
              "  events.on('clear_output.CodeCell', handle_clear_output);\n",
              "  events.on('delete.Cell', handle_clear_output);\n",
              "  events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n",
              "\n",
              "  OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
              "    safe: true,\n",
              "    index: 0\n",
              "  });\n",
              "}\n",
              "\n",
              "if (window.Jupyter !== undefined) {\n",
              "  try {\n",
              "    var events = require('base/js/events');\n",
              "    var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
              "    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
              "      register_renderer(events, OutputArea);\n",
              "    }\n",
              "  } catch(err) {\n",
              "  }\n",
              "}\n"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<style>*[data-root-id],\n",
              "*[data-root-id] > * {\n",
              "  box-sizing: border-box;\n",
              "  font-family: var(--jp-ui-font-family);\n",
              "  font-size: var(--jp-ui-font-size1);\n",
              "  color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
              "}\n",
              "\n",
              "/* Override VSCode background color */\n",
              ".cell-output-ipywidget-background:has(\n",
              "    > .cell-output-ipywidget-background > .lm-Widget > *[data-root-id]\n",
              "  ),\n",
              ".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
              "  background-color: transparent !important;\n",
              "}\n",
              "</style>"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<div id='3fd82b27-d76e-4d80-bd93-ca40c3746da2'>\n",
              "  <div id=\"fa80e8e6-a10e-4528-b744-e0e7d4c31d6e\" data-root-id=\"3fd82b27-d76e-4d80-bd93-ca40c3746da2\" style=\"display: contents;\"></div>\n",
              "</div>\n",
              "<script type=\"application/javascript\">(function(root) {\n",
              "  var docs_json = {\"5381d3a9-fc8a-4095-80fc-f3980a04516d\":{\"version\":\"3.3.0\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"panel.models.browser.BrowserInfo\",\"id\":\"3fd82b27-d76e-4d80-bd93-ca40c3746da2\"},{\"type\":\"object\",\"name\":\"panel.models.comm_manager.CommManager\",\"id\":\"b4d7dece-de10-4ade-9c26-2e9078b2b278\",\"attributes\":{\"plot_id\":\"3fd82b27-d76e-4d80-bd93-ca40c3746da2\",\"comm_id\":\"4e36e2e853f5413fb9ea6004ca55cf61\",\"client_comm_id\":\"c463a724bebc4c1bbc329e859516d4fd\"}}],\"defs\":[{\"type\":\"model\",\"name\":\"ReactiveHTML1\"},{\"type\":\"model\",\"name\":\"FlexBox1\",\"properties\":[{\"name\":\"align_content\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"align_items\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"flex_direction\",\"kind\":\"Any\",\"default\":\"row\"},{\"name\":\"flex_wrap\",\"kind\":\"Any\",\"default\":\"wrap\"},{\"name\":\"justify_content\",\"kind\":\"Any\",\"default\":\"flex-start\"}]},{\"type\":\"model\",\"name\":\"FloatPanel1\",\"properties\":[{\"name\":\"config\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"contained\",\"kind\":\"Any\",\"default\":true},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"right-top\"},{\"name\":\"offsetx\",\"kind\":\"Any\",\"default\":null},{\"name\":\"offsety\",\"kind\":\"Any\",\"default\":null},{\"name\":\"theme\",\"kind\":\"Any\",\"default\":\"primary\"},{\"name\":\"status\",\"kind\":\"Any\",\"default\":\"normalized\"}]},{\"type\":\"model\",\"name\":\"GridStack1\",\"properties\":[{\"name\":\"mode\",\"kind\":\"Any\",\"default\":\"warn\"},{\"name\":\"ncols\",\"kind\":\"Any\",\"default\":null},{\"name\":\"nrows\",\"kind\":\"Any\",\"default\":null},{\"name\":\"allow_resize\",\"kind\":\"Any\",\"default\":true},{\"name\":\"allow_drag\",\"kind\":\"Any\",\"default\":true},{\"name\":\"state\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"drag1\",\"properties\":[{\"name\":\"slider_width\",\"kind\":\"Any\",\"default\":5},{\"name\":\"slider_color\",\"kind\":\"Any\",\"default\":\"black\"},{\"name\":\"value\",\"kind\":\"Any\",\"default\":50}]},{\"type\":\"model\",\"name\":\"click1\",\"properties\":[{\"name\":\"terminal_output\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"debug_name\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"clears\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"toggle_value1\",\"properties\":[{\"name\":\"active_icons\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"options\",\"kind\":\"Any\",\"default\":{\"type\":\"map\",\"entries\":[[\"favorite\",\"heart\"]]}},{\"name\":\"value\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"_reactions\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"_base_url\",\"kind\":\"Any\",\"default\":\"https://tabler-icons.io/static/tabler-icons/icons/\"}]},{\"type\":\"model\",\"name\":\"copy_to_clipboard1\",\"properties\":[{\"name\":\"value\",\"kind\":\"Any\",\"default\":null},{\"name\":\"fill\",\"kind\":\"Any\",\"default\":\"none\"}]},{\"type\":\"model\",\"name\":\"FastWrapper1\",\"properties\":[{\"name\":\"object\",\"kind\":\"Any\",\"default\":null},{\"name\":\"style\",\"kind\":\"Any\",\"default\":null}]},{\"type\":\"model\",\"name\":\"NotificationAreaBase1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"NotificationArea1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"notifications\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0},{\"name\":\"types\",\"kind\":\"Any\",\"default\":[{\"type\":\"map\",\"entries\":[[\"type\",\"warning\"],[\"background\",\"#ffc107\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-exclamation-triangle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]},{\"type\":\"map\",\"entries\":[[\"type\",\"info\"],[\"background\",\"#007bff\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-info-circle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]}]}]},{\"type\":\"model\",\"name\":\"Notification\",\"properties\":[{\"name\":\"background\",\"kind\":\"Any\",\"default\":null},{\"name\":\"duration\",\"kind\":\"Any\",\"default\":3000},{\"name\":\"icon\",\"kind\":\"Any\",\"default\":null},{\"name\":\"message\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"notification_type\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_destroyed\",\"kind\":\"Any\",\"default\":false}]},{\"type\":\"model\",\"name\":\"TemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"BootstrapTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"MaterialTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]}]}};\n",
              "  var render_items = [{\"docid\":\"5381d3a9-fc8a-4095-80fc-f3980a04516d\",\"roots\":{\"3fd82b27-d76e-4d80-bd93-ca40c3746da2\":\"fa80e8e6-a10e-4528-b744-e0e7d4c31d6e\"},\"root_ids\":[\"3fd82b27-d76e-4d80-bd93-ca40c3746da2\"]}];\n",
              "  var docs = Object.values(docs_json)\n",
              "  if (!docs) {\n",
              "    return\n",
              "  }\n",
              "  const py_version = docs[0].version.replace('rc', '-rc.').replace('.dev', '-dev.')\n",
              "  const is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1\n",
              "  function embed_document(root) {\n",
              "    var Bokeh = get_bokeh(root)\n",
              "    Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
              "    for (const render_item of render_items) {\n",
              "      for (const root_id of render_item.root_ids) {\n",
              "\tconst id_el = document.getElementById(root_id)\n",
              "\tif (id_el.children.length && (id_el.children[0].className === 'bk-root')) {\n",
              "\t  const root_el = id_el.children[0]\n",
              "\t  root_el.id = root_el.id + '-rendered'\n",
              "\t}\n",
              "      }\n",
              "    }\n",
              "  }\n",
              "  function get_bokeh(root) {\n",
              "    if (root.Bokeh === undefined) {\n",
              "      return null\n",
              "    } else if (root.Bokeh.version !== py_version && !is_dev) {\n",
              "      if (root.Bokeh.versions === undefined || !root.Bokeh.versions.has(py_version)) {\n",
              "\treturn null\n",
              "      }\n",
              "      return root.Bokeh.versions.get(py_version);\n",
              "    } else if (root.Bokeh.version === py_version) {\n",
              "      return root.Bokeh\n",
              "    }\n",
              "    return null\n",
              "  }\n",
              "  function is_loaded(root) {\n",
              "    var Bokeh = get_bokeh(root)\n",
              "    return (Bokeh != null && Bokeh.Panel !== undefined)\n",
              "  }\n",
              "  if (is_loaded(root)) {\n",
              "    embed_document(root);\n",
              "  } else {\n",
              "    var attempts = 0;\n",
              "    var timer = setInterval(function(root) {\n",
              "      if (is_loaded(root)) {\n",
              "        clearInterval(timer);\n",
              "        embed_document(root);\n",
              "      } else if (document.readyState == \"complete\") {\n",
              "        attempts++;\n",
              "        if (attempts > 200) {\n",
              "          clearInterval(timer);\n",
              "\t  var Bokeh = get_bokeh(root)\n",
              "\t  if (Bokeh == null || Bokeh.Panel == null) {\n",
              "            console.warn(\"Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing\");\n",
              "\t  } else {\n",
              "\t    console.warn(\"Panel: WARNING: Attempting to render but not all required libraries could be resolved.\")\n",
              "\t    embed_document(root)\n",
              "\t  }\n",
              "        }\n",
              "      }\n",
              "    }, 25, root)\n",
              "  }\n",
              "})(window);</script>"
            ],
            "application/vnd.holoviews_exec.v0+json": ""
          },
          "metadata": {
            "application/vnd.holoviews_exec.v0+json": {
              "id": "3fd82b27-d76e-4d80-bd93-ca40c3746da2"
            }
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "application/javascript": [
              "(function(root) {\n",
              "  function now() {\n",
              "    return new Date();\n",
              "  }\n",
              "\n",
              "  var force = true;\n",
              "  var py_version = '3.3.0'.replace('rc', '-rc.').replace('.dev', '-dev.');\n",
              "  var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n",
              "  var reloading = false;\n",
              "  var Bokeh = root.Bokeh;\n",
              "  var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n",
              "\n",
              "  if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n",
              "    root._bokeh_timeout = Date.now() + 5000;\n",
              "    root._bokeh_failed_load = false;\n",
              "  }\n",
              "\n",
              "  function run_callbacks() {\n",
              "    try {\n",
              "      root._bokeh_onload_callbacks.forEach(function(callback) {\n",
              "        if (callback != null)\n",
              "          callback();\n",
              "      });\n",
              "    } finally {\n",
              "      delete root._bokeh_onload_callbacks;\n",
              "    }\n",
              "    console.debug(\"Bokeh: all callbacks have finished\");\n",
              "  }\n",
              "\n",
              "  function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n",
              "    if (css_urls == null) css_urls = [];\n",
              "    if (js_urls == null) js_urls = [];\n",
              "    if (js_modules == null) js_modules = [];\n",
              "    if (js_exports == null) js_exports = {};\n",
              "\n",
              "    root._bokeh_onload_callbacks.push(callback);\n",
              "\n",
              "    if (root._bokeh_is_loading > 0) {\n",
              "      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
              "      return null;\n",
              "    }\n",
              "    if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n",
              "      run_callbacks();\n",
              "      return null;\n",
              "    }\n",
              "    if (!reloading) {\n",
              "      console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
              "    }\n",
              "\n",
              "    function on_load() {\n",
              "      root._bokeh_is_loading--;\n",
              "      if (root._bokeh_is_loading === 0) {\n",
              "        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n",
              "        run_callbacks()\n",
              "      }\n",
              "    }\n",
              "    window._bokeh_on_load = on_load\n",
              "\n",
              "    function on_error() {\n",
              "      console.error(\"failed to load \" + url);\n",
              "    }\n",
              "\n",
              "    var skip = [];\n",
              "    if (window.requirejs) {\n",
              "      window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n",
              "      require([\"jspanel\"], function(jsPanel) {\n",
              "\twindow.jsPanel = jsPanel\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-modal\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-tooltip\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-hint\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-layout\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-contextmenu\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"jspanel-dock\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"gridstack\"], function(GridStack) {\n",
              "\twindow.GridStack = GridStack\n",
              "\ton_load()\n",
              "      })\n",
              "      require([\"notyf\"], function() {\n",
              "\ton_load()\n",
              "      })\n",
              "      root._bokeh_is_loading = css_urls.length + 9;\n",
              "    } else {\n",
              "      root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n",
              "    }\n",
              "\n",
              "    var existing_stylesheets = []\n",
              "    var links = document.getElementsByTagName('link')\n",
              "    for (var i = 0; i < links.length; i++) {\n",
              "      var link = links[i]\n",
              "      if (link.href != null) {\n",
              "\texisting_stylesheets.push(link.href)\n",
              "      }\n",
              "    }\n",
              "    for (var i = 0; i < css_urls.length; i++) {\n",
              "      var url = css_urls[i];\n",
              "      if (existing_stylesheets.indexOf(url) !== -1) {\n",
              "\ton_load()\n",
              "\tcontinue;\n",
              "      }\n",
              "      const element = document.createElement(\"link\");\n",
              "      element.onload = on_load;\n",
              "      element.onerror = on_error;\n",
              "      element.rel = \"stylesheet\";\n",
              "      element.type = \"text/css\";\n",
              "      element.href = url;\n",
              "      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n",
              "      document.body.appendChild(element);\n",
              "    }    if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n",
              "      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n",
              "      for (var i = 0; i < urls.length; i++) {\n",
              "        skip.push(urls[i])\n",
              "      }\n",
              "    }    if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n",
              "      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n",
              "      for (var i = 0; i < urls.length; i++) {\n",
              "        skip.push(urls[i])\n",
              "      }\n",
              "    }    if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n",
              "      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n",
              "      for (var i = 0; i < urls.length; i++) {\n",
              "        skip.push(urls[i])\n",
              "      }\n",
              "    }    var existing_scripts = []\n",
              "    var scripts = document.getElementsByTagName('script')\n",
              "    for (var i = 0; i < scripts.length; i++) {\n",
              "      var script = scripts[i]\n",
              "      if (script.src != null) {\n",
              "\texisting_scripts.push(script.src)\n",
              "      }\n",
              "    }\n",
              "    for (var i = 0; i < js_urls.length; i++) {\n",
              "      var url = js_urls[i];\n",
              "      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n",
              "\tif (!window.requirejs) {\n",
              "\t  on_load();\n",
              "\t}\n",
              "\tcontinue;\n",
              "      }\n",
              "      var element = document.createElement('script');\n",
              "      element.onload = on_load;\n",
              "      element.onerror = on_error;\n",
              "      element.async = false;\n",
              "      element.src = url;\n",
              "      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
              "      document.head.appendChild(element);\n",
              "    }\n",
              "    for (var i = 0; i < js_modules.length; i++) {\n",
              "      var url = js_modules[i];\n",
              "      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n",
              "\tif (!window.requirejs) {\n",
              "\t  on_load();\n",
              "\t}\n",
              "\tcontinue;\n",
              "      }\n",
              "      var element = document.createElement('script');\n",
              "      element.onload = on_load;\n",
              "      element.onerror = on_error;\n",
              "      element.async = false;\n",
              "      element.src = url;\n",
              "      element.type = \"module\";\n",
              "      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
              "      document.head.appendChild(element);\n",
              "    }\n",
              "    for (const name in js_exports) {\n",
              "      var url = js_exports[name];\n",
              "      if (skip.indexOf(url) >= 0 || root[name] != null) {\n",
              "\tif (!window.requirejs) {\n",
              "\t  on_load();\n",
              "\t}\n",
              "\tcontinue;\n",
              "      }\n",
              "      var element = document.createElement('script');\n",
              "      element.onerror = on_error;\n",
              "      element.async = false;\n",
              "      element.type = \"module\";\n",
              "      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
              "      element.textContent = `\n",
              "      import ${name} from \"${url}\"\n",
              "      window.${name} = ${name}\n",
              "      window._bokeh_on_load()\n",
              "      `\n",
              "      document.head.appendChild(element);\n",
              "    }\n",
              "    if (!js_urls.length && !js_modules.length) {\n",
              "      on_load()\n",
              "    }\n",
              "  };\n",
              "\n",
              "  function inject_raw_css(css) {\n",
              "    const element = document.createElement(\"style\");\n",
              "    element.appendChild(document.createTextNode(css));\n",
              "    document.body.appendChild(element);\n",
              "  }\n",
              "\n",
              "  var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.0.min.js\", \"https://cdn.holoviz.org/panel/1.3.1/dist/panel.min.js\"];\n",
              "  var js_modules = [];\n",
              "  var js_exports = {};\n",
              "  var css_urls = [];\n",
              "  var inline_js = [    function(Bokeh) {\n",
              "      Bokeh.set_log_level(\"info\");\n",
              "    },\n",
              "function(Bokeh) {} // ensure no trailing comma for IE\n",
              "  ];\n",
              "\n",
              "  function run_inline_js() {\n",
              "    if ((root.Bokeh !== undefined) || (force === true)) {\n",
              "      for (var i = 0; i < inline_js.length; i++) {\n",
              "        inline_js[i].call(root, root.Bokeh);\n",
              "      }\n",
              "      // Cache old bokeh versions\n",
              "      if (Bokeh != undefined && !reloading) {\n",
              "\tvar NewBokeh = root.Bokeh;\n",
              "\tif (Bokeh.versions === undefined) {\n",
              "\t  Bokeh.versions = new Map();\n",
              "\t}\n",
              "\tif (NewBokeh.version !== Bokeh.version) {\n",
              "\t  Bokeh.versions.set(NewBokeh.version, NewBokeh)\n",
              "\t}\n",
              "\troot.Bokeh = Bokeh;\n",
              "      }} else if (Date.now() < root._bokeh_timeout) {\n",
              "      setTimeout(run_inline_js, 100);\n",
              "    } else if (!root._bokeh_failed_load) {\n",
              "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
              "      root._bokeh_failed_load = true;\n",
              "    }\n",
              "    root._bokeh_is_initializing = false\n",
              "  }\n",
              "\n",
              "  function load_or_wait() {\n",
              "    // Implement a backoff loop that tries to ensure we do not load multiple\n",
              "    // versions of Bokeh and its dependencies at the same time.\n",
              "    // In recent versions we use the root._bokeh_is_initializing flag\n",
              "    // to determine whether there is an ongoing attempt to initialize\n",
              "    // bokeh, however for backward compatibility we also try to ensure\n",
              "    // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n",
              "    // before older versions are fully initialized.\n",
              "    if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n",
              "      root._bokeh_is_initializing = false;\n",
              "      root._bokeh_onload_callbacks = undefined;\n",
              "      console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n",
              "      load_or_wait();\n",
              "    } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n",
              "      setTimeout(load_or_wait, 100);\n",
              "    } else {\n",
              "      Bokeh = root.Bokeh;\n",
              "      bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n",
              "      root._bokeh_is_initializing = true\n",
              "      root._bokeh_onload_callbacks = []\n",
              "      if (!reloading && (!bokeh_loaded || is_dev)) {\n",
              "\troot.Bokeh = undefined;\n",
              "      }\n",
              "      load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n",
              "\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n",
              "\trun_inline_js();\n",
              "      });\n",
              "    }\n",
              "  }\n",
              "  // Give older versions of the autoload script a head-start to ensure\n",
              "  // they initialize before we start loading newer version.\n",
              "  setTimeout(load_or_wait, 100)\n",
              "}(window));"
            ],
            "application/vnd.holoviews_load.v0+json": "(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  var force = true;\n  var py_version = '3.3.0'.replace('rc', '-rc.').replace('.dev', '-dev.');\n  var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n  var reloading = false;\n  var Bokeh = root.Bokeh;\n  var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n  if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) {\n        if (callback != null)\n          callback();\n      });\n    } finally {\n      delete root._bokeh_onload_callbacks;\n    }\n    console.debug(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n    if (css_urls == null) css_urls = [];\n    if (js_urls == null) js_urls = [];\n    if (js_modules == null) js_modules = [];\n    if (js_exports == null) js_exports = {};\n\n    root._bokeh_onload_callbacks.push(callback);\n\n    if (root._bokeh_is_loading > 0) {\n      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n      run_callbacks();\n      return null;\n    }\n    if (!reloading) {\n      console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    }\n\n    function on_load() {\n      root._bokeh_is_loading--;\n      if (root._bokeh_is_loading === 0) {\n        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n        run_callbacks()\n      }\n    }\n    window._bokeh_on_load = on_load\n\n    function on_error() {\n      console.error(\"failed to load \" + url);\n    }\n\n    var skip = [];\n    if (window.requirejs) {\n      window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n      require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n      })\n      require([\"jspanel-modal\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-tooltip\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-hint\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-layout\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n      })\n      require([\"jspanel-dock\"], function() {\n\ton_load()\n      })\n      require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n      })\n      require([\"notyf\"], function() {\n\ton_load()\n      })\n      root._bokeh_is_loading = css_urls.length + 9;\n    } else {\n      root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n    }\n\n    var existing_stylesheets = []\n    var links = document.getElementsByTagName('link')\n    for (var i = 0; i < links.length; i++) {\n      var link = links[i]\n      if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n      }\n    }\n    for (var i = 0; i < css_urls.length; i++) {\n      var url = css_urls[i];\n      if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n      }\n      const element = document.createElement(\"link\");\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.rel = \"stylesheet\";\n      element.type = \"text/css\";\n      element.href = url;\n      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n      document.body.appendChild(element);\n    }    if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.3.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(urls[i])\n      }\n    }    if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(urls[i])\n      }\n    }    if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.3.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(urls[i])\n      }\n    }    var existing_scripts = []\n    var scripts = document.getElementsByTagName('script')\n    for (var i = 0; i < scripts.length; i++) {\n      var script = scripts[i]\n      if (script.src != null) {\n\texisting_scripts.push(script.src)\n      }\n    }\n    for (var i = 0; i < js_urls.length; i++) {\n      var url = js_urls[i];\n      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t  on_load();\n\t}\n\tcontinue;\n      }\n      var element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (var i = 0; i < js_modules.length; i++) {\n      var url = js_modules[i];\n      if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t  on_load();\n\t}\n\tcontinue;\n      }\n      var element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (const name in js_exports) {\n      var url = js_exports[name];\n      if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t  on_load();\n\t}\n\tcontinue;\n      }\n      var element = document.createElement('script');\n      element.onerror = on_error;\n      element.async = false;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      element.textContent = `\n      import ${name} from \"${url}\"\n      window.${name} = ${name}\n      window._bokeh_on_load()\n      `\n      document.head.appendChild(element);\n    }\n    if (!js_urls.length && !js_modules.length) {\n      on_load()\n    }\n  };\n\n  function inject_raw_css(css) {\n    const element = document.createElement(\"style\");\n    element.appendChild(document.createTextNode(css));\n    document.body.appendChild(element);\n  }\n\n  var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.0.min.js\", \"https://cdn.holoviz.org/panel/1.3.1/dist/panel.min.js\"];\n  var js_modules = [];\n  var js_exports = {};\n  var css_urls = [];\n  var inline_js = [    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n  ];\n\n  function run_inline_js() {\n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (var i = 0; i < inline_js.length; i++) {\n        inline_js[i].call(root, root.Bokeh);\n      }\n      // Cache old bokeh versions\n      if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t  Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t  Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    }\n    root._bokeh_is_initializing = false\n  }\n\n  function load_or_wait() {\n    // Implement a backoff loop that tries to ensure we do not load multiple\n    // versions of Bokeh and its dependencies at the same time.\n    // In recent versions we use the root._bokeh_is_initializing flag\n    // to determine whether there is an ongoing attempt to initialize\n    // bokeh, however for backward compatibility we also try to ensure\n    // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n    // before older versions are fully initialized.\n    if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n      root._bokeh_is_initializing = false;\n      root._bokeh_onload_callbacks = undefined;\n      console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n      load_or_wait();\n    } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n      setTimeout(load_or_wait, 100);\n    } else {\n      Bokeh = root.Bokeh;\n      bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n      root._bokeh_is_initializing = true\n      root._bokeh_onload_callbacks = []\n      if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n      }\n      load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n      });\n    }\n  }\n  // Give older versions of the autoload script a head-start to ensure\n  // they initialize before we start loading newer version.\n  setTimeout(load_or_wait, 100)\n}(window));"
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n  window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n    function JupyterCommManager() {\n    }\n\n    JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n      if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        comm_manager.register_target(comm_id, function(comm) {\n          comm.on_msg(msg_handler);\n        });\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n          comm.onMsg = msg_handler;\n        });\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n          var messages = comm.messages[Symbol.asyncIterator]();\n          function processIteratorResult(result) {\n            var message = result.value;\n            console.log(message)\n            var content = {data: message.data, comm_id};\n            var buffers = []\n            for (var buffer of message.buffers || []) {\n              buffers.push(new DataView(buffer))\n            }\n            var metadata = message.metadata || {};\n            var msg = {content, buffers, metadata}\n            msg_handler(msg);\n            return messages.next().then(processIteratorResult);\n          }\n          return messages.next().then(processIteratorResult);\n        })\n      }\n    }\n\n    JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n      if (comm_id in window.PyViz.comms) {\n        return window.PyViz.comms[comm_id];\n      } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n        if (msg_handler) {\n          comm.on_msg(msg_handler);\n        }\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n        comm.open();\n        if (msg_handler) {\n          comm.onMsg = msg_handler;\n        }\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        var comm_promise = google.colab.kernel.comms.open(comm_id)\n        comm_promise.then((comm) => {\n          window.PyViz.comms[comm_id] = comm;\n          if (msg_handler) {\n            var messages = comm.messages[Symbol.asyncIterator]();\n            function processIteratorResult(result) {\n              var message = result.value;\n              var content = {data: message.data};\n              var metadata = message.metadata || {comm_id};\n              var msg = {content, metadata}\n              msg_handler(msg);\n              return messages.next().then(processIteratorResult);\n            }\n            return messages.next().then(processIteratorResult);\n          }\n        }) \n        var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n          return comm_promise.then((comm) => {\n            comm.send(data, metadata, buffers, disposeOnDone);\n          });\n        };\n        var comm = {\n          send: sendClosure\n        };\n      }\n      window.PyViz.comms[comm_id] = comm;\n      return comm;\n    }\n    window.PyViz.comm_manager = new JupyterCommManager();\n    \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n  var div = document.createElement(\"div\");\n  var script = document.createElement(\"script\");\n  node.appendChild(div);\n  node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n  var output_area = handle.output_area;\n  var output = handle.output;\n  if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n    return\n  }\n  var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n  var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n  if (id !== undefined) {\n    var nchildren = toinsert.length;\n    var html_node = toinsert[nchildren-1].children[0];\n    html_node.innerHTML = output.data[HTML_MIME_TYPE];\n    var scripts = [];\n    var nodelist = html_node.querySelectorAll(\"script\");\n    for (var i in nodelist) {\n      if (nodelist.hasOwnProperty(i)) {\n        scripts.push(nodelist[i])\n      }\n    }\n\n    scripts.forEach( function (oldScript) {\n      var newScript = document.createElement(\"script\");\n      var attrs = [];\n      var nodemap = oldScript.attributes;\n      for (var j in nodemap) {\n        if (nodemap.hasOwnProperty(j)) {\n          attrs.push(nodemap[j])\n        }\n      }\n      attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n      newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n      oldScript.parentNode.replaceChild(newScript, oldScript);\n    });\n    if (JS_MIME_TYPE in output.data) {\n      toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n    }\n    output_area._hv_plot_id = id;\n    if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n      window.PyViz.plot_index[id] = Bokeh.index[id];\n    } else {\n      window.PyViz.plot_index[id] = null;\n    }\n  } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n    var bk_div = document.createElement(\"div\");\n    bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n    var script_attrs = bk_div.children[0].attributes;\n    for (var i = 0; i < script_attrs.length; i++) {\n      toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n    }\n    // store reference to server id on output_area\n    output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n  }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n  var id = handle.cell.output_area._hv_plot_id;\n  var server_id = handle.cell.output_area._bokeh_server_id;\n  if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n  var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n  if (server_id !== null) {\n    comm.send({event_type: 'server_delete', 'id': server_id});\n    return;\n  } else if (comm !== null) {\n    comm.send({event_type: 'delete', 'id': id});\n  }\n  delete PyViz.plot_index[id];\n  if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n    var doc = window.Bokeh.index[id].model.document\n    doc.clear();\n    const i = window.Bokeh.documents.indexOf(doc);\n    if (i > -1) {\n      window.Bokeh.documents.splice(i, 1);\n    }\n  }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n  delete PyViz.comms[\"hv-extension-comm\"];\n  window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n  handle_clear_output(event, {cell: {output_area: handle.output_area}})\n  handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n  function append_mime(data, metadata, element) {\n    // create a DOM node to render to\n    var toinsert = this.create_output_subarea(\n    metadata,\n    CLASS_NAME,\n    EXEC_MIME_TYPE\n    );\n    this.keyboard_manager.register_events(toinsert);\n    // Render to node\n    var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n    render(props, toinsert[0]);\n    element.append(toinsert);\n    return toinsert\n  }\n\n  events.on('output_added.OutputArea', handle_add_output);\n  events.on('output_updated.OutputArea', handle_update_output);\n  events.on('clear_output.CodeCell', handle_clear_output);\n  events.on('delete.Cell', handle_clear_output);\n  events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n  OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n    safe: true,\n    index: 0\n  });\n}\n\nif (window.Jupyter !== undefined) {\n  try {\n    var events = require('base/js/events');\n    var OutputArea = require('notebook/js/outputarea').OutputArea;\n    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n      register_renderer(events, OutputArea);\n    }\n  } catch(err) {\n  }\n}\n",
            "application/javascript": [
              "\n",
              "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n",
              "  window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n",
              "}\n",
              "\n",
              "\n",
              "    function JupyterCommManager() {\n",
              "    }\n",
              "\n",
              "    JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n",
              "      if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
              "        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
              "        comm_manager.register_target(comm_id, function(comm) {\n",
              "          comm.on_msg(msg_handler);\n",
              "        });\n",
              "      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
              "        window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n",
              "          comm.onMsg = msg_handler;\n",
              "        });\n",
              "      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
              "        google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n",
              "          var messages = comm.messages[Symbol.asyncIterator]();\n",
              "          function processIteratorResult(result) {\n",
              "            var message = result.value;\n",
              "            console.log(message)\n",
              "            var content = {data: message.data, comm_id};\n",
              "            var buffers = []\n",
              "            for (var buffer of message.buffers || []) {\n",
              "              buffers.push(new DataView(buffer))\n",
              "            }\n",
              "            var metadata = message.metadata || {};\n",
              "            var msg = {content, buffers, metadata}\n",
              "            msg_handler(msg);\n",
              "            return messages.next().then(processIteratorResult);\n",
              "          }\n",
              "          return messages.next().then(processIteratorResult);\n",
              "        })\n",
              "      }\n",
              "    }\n",
              "\n",
              "    JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n",
              "      if (comm_id in window.PyViz.comms) {\n",
              "        return window.PyViz.comms[comm_id];\n",
              "      } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
              "        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
              "        var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n",
              "        if (msg_handler) {\n",
              "          comm.on_msg(msg_handler);\n",
              "        }\n",
              "      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
              "        var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n",
              "        comm.open();\n",
              "        if (msg_handler) {\n",
              "          comm.onMsg = msg_handler;\n",
              "        }\n",
              "      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
              "        var comm_promise = google.colab.kernel.comms.open(comm_id)\n",
              "        comm_promise.then((comm) => {\n",
              "          window.PyViz.comms[comm_id] = comm;\n",
              "          if (msg_handler) {\n",
              "            var messages = comm.messages[Symbol.asyncIterator]();\n",
              "            function processIteratorResult(result) {\n",
              "              var message = result.value;\n",
              "              var content = {data: message.data};\n",
              "              var metadata = message.metadata || {comm_id};\n",
              "              var msg = {content, metadata}\n",
              "              msg_handler(msg);\n",
              "              return messages.next().then(processIteratorResult);\n",
              "            }\n",
              "            return messages.next().then(processIteratorResult);\n",
              "          }\n",
              "        }) \n",
              "        var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n",
              "          return comm_promise.then((comm) => {\n",
              "            comm.send(data, metadata, buffers, disposeOnDone);\n",
              "          });\n",
              "        };\n",
              "        var comm = {\n",
              "          send: sendClosure\n",
              "        };\n",
              "      }\n",
              "      window.PyViz.comms[comm_id] = comm;\n",
              "      return comm;\n",
              "    }\n",
              "    window.PyViz.comm_manager = new JupyterCommManager();\n",
              "    \n",
              "\n",
              "\n",
              "var JS_MIME_TYPE = 'application/javascript';\n",
              "var HTML_MIME_TYPE = 'text/html';\n",
              "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n",
              "var CLASS_NAME = 'output';\n",
              "\n",
              "/**\n",
              " * Render data to the DOM node\n",
              " */\n",
              "function render(props, node) {\n",
              "  var div = document.createElement(\"div\");\n",
              "  var script = document.createElement(\"script\");\n",
              "  node.appendChild(div);\n",
              "  node.appendChild(script);\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle when a new output is added\n",
              " */\n",
              "function handle_add_output(event, handle) {\n",
              "  var output_area = handle.output_area;\n",
              "  var output = handle.output;\n",
              "  if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
              "    return\n",
              "  }\n",
              "  var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
              "  var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
              "  if (id !== undefined) {\n",
              "    var nchildren = toinsert.length;\n",
              "    var html_node = toinsert[nchildren-1].children[0];\n",
              "    html_node.innerHTML = output.data[HTML_MIME_TYPE];\n",
              "    var scripts = [];\n",
              "    var nodelist = html_node.querySelectorAll(\"script\");\n",
              "    for (var i in nodelist) {\n",
              "      if (nodelist.hasOwnProperty(i)) {\n",
              "        scripts.push(nodelist[i])\n",
              "      }\n",
              "    }\n",
              "\n",
              "    scripts.forEach( function (oldScript) {\n",
              "      var newScript = document.createElement(\"script\");\n",
              "      var attrs = [];\n",
              "      var nodemap = oldScript.attributes;\n",
              "      for (var j in nodemap) {\n",
              "        if (nodemap.hasOwnProperty(j)) {\n",
              "          attrs.push(nodemap[j])\n",
              "        }\n",
              "      }\n",
              "      attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n",
              "      newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n",
              "      oldScript.parentNode.replaceChild(newScript, oldScript);\n",
              "    });\n",
              "    if (JS_MIME_TYPE in output.data) {\n",
              "      toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n",
              "    }\n",
              "    output_area._hv_plot_id = id;\n",
              "    if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n",
              "      window.PyViz.plot_index[id] = Bokeh.index[id];\n",
              "    } else {\n",
              "      window.PyViz.plot_index[id] = null;\n",
              "    }\n",
              "  } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
              "    var bk_div = document.createElement(\"div\");\n",
              "    bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
              "    var script_attrs = bk_div.children[0].attributes;\n",
              "    for (var i = 0; i < script_attrs.length; i++) {\n",
              "      toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
              "    }\n",
              "    // store reference to server id on output_area\n",
              "    output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
              "  }\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle when an output is cleared or removed\n",
              " */\n",
              "function handle_clear_output(event, handle) {\n",
              "  var id = handle.cell.output_area._hv_plot_id;\n",
              "  var server_id = handle.cell.output_area._bokeh_server_id;\n",
              "  if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n",
              "  var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n",
              "  if (server_id !== null) {\n",
              "    comm.send({event_type: 'server_delete', 'id': server_id});\n",
              "    return;\n",
              "  } else if (comm !== null) {\n",
              "    comm.send({event_type: 'delete', 'id': id});\n",
              "  }\n",
              "  delete PyViz.plot_index[id];\n",
              "  if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n",
              "    var doc = window.Bokeh.index[id].model.document\n",
              "    doc.clear();\n",
              "    const i = window.Bokeh.documents.indexOf(doc);\n",
              "    if (i > -1) {\n",
              "      window.Bokeh.documents.splice(i, 1);\n",
              "    }\n",
              "  }\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle kernel restart event\n",
              " */\n",
              "function handle_kernel_cleanup(event, handle) {\n",
              "  delete PyViz.comms[\"hv-extension-comm\"];\n",
              "  window.PyViz.plot_index = {}\n",
              "}\n",
              "\n",
              "/**\n",
              " * Handle update_display_data messages\n",
              " */\n",
              "function handle_update_output(event, handle) {\n",
              "  handle_clear_output(event, {cell: {output_area: handle.output_area}})\n",
              "  handle_add_output(event, handle)\n",
              "}\n",
              "\n",
              "function register_renderer(events, OutputArea) {\n",
              "  function append_mime(data, metadata, element) {\n",
              "    // create a DOM node to render to\n",
              "    var toinsert = this.create_output_subarea(\n",
              "    metadata,\n",
              "    CLASS_NAME,\n",
              "    EXEC_MIME_TYPE\n",
              "    );\n",
              "    this.keyboard_manager.register_events(toinsert);\n",
              "    // Render to node\n",
              "    var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
              "    render(props, toinsert[0]);\n",
              "    element.append(toinsert);\n",
              "    return toinsert\n",
              "  }\n",
              "\n",
              "  events.on('output_added.OutputArea', handle_add_output);\n",
              "  events.on('output_updated.OutputArea', handle_update_output);\n",
              "  events.on('clear_output.CodeCell', handle_clear_output);\n",
              "  events.on('delete.Cell', handle_clear_output);\n",
              "  events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n",
              "\n",
              "  OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
              "    safe: true,\n",
              "    index: 0\n",
              "  });\n",
              "}\n",
              "\n",
              "if (window.Jupyter !== undefined) {\n",
              "  try {\n",
              "    var events = require('base/js/events');\n",
              "    var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
              "    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
              "      register_renderer(events, OutputArea);\n",
              "    }\n",
              "  } catch(err) {\n",
              "  }\n",
              "}\n"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "<style>*[data-root-id],\n",
              "*[data-root-id] > * {\n",
              "  box-sizing: border-box;\n",
              "  font-family: var(--jp-ui-font-family);\n",
              "  font-size: var(--jp-ui-font-size1);\n",
              "  color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
              "}\n",
              "\n",
              "/* Override VSCode background color */\n",
              ".cell-output-ipywidget-background:has(\n",
              "    > .cell-output-ipywidget-background > .lm-Widget > *[data-root-id]\n",
              "  ),\n",
              ".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
              "  background-color: transparent !important;\n",
              "}\n",
              "</style>"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {},
          "metadata": {}
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div id='db05b70e-70bd-4901-9290-1fcbf1b561db'>\n",
              "  <div id=\"b1aa7761-4cfe-466a-8aa1-781707e0fd3b\" data-root-id=\"db05b70e-70bd-4901-9290-1fcbf1b561db\" style=\"display: contents;\"></div>\n",
              "</div>\n",
              "<script type=\"application/javascript\">(function(root) {\n",
              "  var docs_json = {\"695a169a-ce62-4a2c-a5ea-e2cfe844999c\":{\"version\":\"3.3.0\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"panel.models.layout.Column\",\"id\":\"db05b70e-70bd-4901-9290-1fcbf1b561db\",\"attributes\":{\"name\":\"Column00212\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"907b6ae8-d430-4f97-97f3-3d5fc91eaa31\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.3.1/dist/css/listpanel.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.3.1/dist/bundled/theme/default.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.3.1/dist/bundled/theme/native.css\"}}],\"margin\":0,\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"TextInput\",\"id\":\"291850a8-a9cd-4c3f-ab79-af7d16094e85\",\"attributes\":{\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"width\":300,\"min_width\":300,\"margin\":[5,10],\"align\":\"start\",\"placeholder\":\"Enter text here\\u2026\",\"max_length\":5000}},{\"type\":\"object\",\"name\":\"Row\",\"id\":\"f2db7880-7ab3-4f4c-82aa-0433e2cbbb05\",\"attributes\":{\"name\":\"Row00157\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"907b6ae8-d430-4f97-97f3-3d5fc91eaa31\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":0,\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"panel.models.widgets.Button\",\"id\":\"cf53a842-90e9-4d13-bb61-5a98a20dacfd\",\"attributes\":{\"js_event_callbacks\":{\"type\":\"map\",\"entries\":[[\"button_click\",[{\"type\":\"object\",\"name\":\"CustomJS\",\"id\":\"9f50b2a7-66d5-4bcd-a4fc-8d1db78221b5\",\"attributes\":{\"tags\":[[139370065999760,[null,\"event:button_click\"],[null,\"loading\"]]],\"args\":{\"type\":\"map\",\"entries\":[[\"bidirectional\",false],[\"properties\",{\"type\":\"map\",\"entries\":[[\"event:button_click\",\"loading\"]]}],[\"source\",{\"id\":\"cf53a842-90e9-4d13-bb61-5a98a20dacfd\"}],[\"target\",{\"type\":\"object\",\"name\":\"panel.models.layout.Column\",\"id\":\"70cb53c6-be2c-445f-8cd6-44bfb8fbf833\",\"attributes\":{\"name\":\"Column00172\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"907b6ae8-d430-4f97-97f3-3d5fc91eaa31\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":0,\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"panel.models.layout.Column\",\"id\":\"c1e55949-fd61-4017-a170-872c14f9e5e8\",\"attributes\":{\"name\":\"Column00206\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"907b6ae8-d430-4f97-97f3-3d5fc91eaa31\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":0,\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"Row\",\"id\":\"05c6b068-54bb-4c0b-b089-3f3bca1878a8\",\"attributes\":{\"name\":\"Row00188\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"907b6ae8-d430-4f97-97f3-3d5fc91eaa31\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":0,\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"panel.models.markup.HTML\",\"id\":\"3165ec4f-c035-4031-8b0e-540cec492dec\",\"attributes\":{\"css_classes\":[\"markdown\"],\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"86190a7c-77d6-46db-b11e-7fa0b269d57c\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.3.1/dist/css/markdown.css\"}},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":[5,10],\"align\":\"start\",\"text\":\"&lt;p&gt;User:&lt;/p&gt;\\n\"}},{\"type\":\"object\",\"name\":\"panel.models.markup.HTML\",\"id\":\"b2c00556-af14-4b48-9017-e866b579ea3c\",\"attributes\":{\"css_classes\":[\"markdown\"],\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"86190a7c-77d6-46db-b11e-7fa0b269d57c\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"width\":600,\"min_width\":600,\"margin\":[5,10],\"align\":\"start\"}}]}},{\"type\":\"object\",\"name\":\"Row\",\"id\":\"f4c3d3f0-7f84-4228-82b0-ee2ca9995dbe\",\"attributes\":{\"name\":\"Row00203\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"907b6ae8-d430-4f97-97f3-3d5fc91eaa31\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":0,\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"panel.models.markup.HTML\",\"id\":\"28da0d73-327a-4947-bb2f-ef5ff1401976\",\"attributes\":{\"css_classes\":[\"markdown\"],\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"86190a7c-77d6-46db-b11e-7fa0b269d57c\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":[5,10],\"align\":\"start\",\"text\":\"&lt;p&gt;Assistant:&lt;/p&gt;\\n\"}},{\"type\":\"object\",\"name\":\"panel.models.markup.HTML\",\"id\":\"55cbf5c3-f77f-4d6d-8d5c-b01676e64d9e\",\"attributes\":{\"css_classes\":[\"markdown\"],\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"id\":\"86190a7c-77d6-46db-b11e-7fa0b269d57c\"},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"width\":600,\"min_width\":600,\"margin\":[5,10],\"align\":\"start\",\"text\":\"&lt;p&gt;Hello! Welcome to My Dear Frankfurt! How can I assist you today?&lt;/p&gt;\\n\"}}]}}]}}]}}]]},\"code\":\"\\n    if ('event:button_click'.startsWith('event:')) {\\n      var value = true\\n    } else {\\n      var value = source['event:button_click'];\\n      value = value;\\n    }\\n    if (typeof value !== 'boolean' || source.labels !== ['Loading']) {\\n      value = true\\n    }\\n    var css_classes = target.css_classes.slice()\\n    var loading_css = ['pn-loading', 'pn-arc']\\n    if (value) {\\n      for (var css of loading_css) {\\n        if (!(css in css_classes)) {\\n          css_classes.push(css)\\n        }\\n      }\\n    } else {\\n     for (var css of loading_css) {\\n        var index = css_classes.indexOf(css)\\n        if (index > -1) {\\n          css_classes.splice(index, 1)\\n        }\\n      }\\n    }\\n    target['css_classes'] = css_classes\\n    \"}}]]]},\"subscribed_events\":{\"type\":\"set\",\"entries\":[\"button_click\"]},\"css_classes\":[\"solid\"],\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n  background-image: url(\\\"\\\");\\n  background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"933ee520-8bbf-43e2-9b2c-e28cbc5c2d07\"},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"7894f2a1-ede1-45f3-8f07-1260eb6266ae\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.3.1/dist/css/button.css\"}},{\"id\":\"d2dea1c9-6c99-4af6-9664-5e595b81e406\"},{\"id\":\"d7d1962c-4d98-466c-ad7e-f42aad304ef9\"}],\"margin\":[5,10],\"align\":\"start\",\"label\":\"talk\"}}]}},{\"id\":\"70cb53c6-be2c-445f-8cd6-44bfb8fbf833\"}]}},{\"type\":\"object\",\"name\":\"panel.models.comm_manager.CommManager\",\"id\":\"be8b2504-6ea1-4fcf-bad2-39834b6431f4\",\"attributes\":{\"plot_id\":\"db05b70e-70bd-4901-9290-1fcbf1b561db\",\"comm_id\":\"bee872caf0174795bba9e5fb2a0daecb\",\"client_comm_id\":\"8ebdf6fb0c98492f8891a6e7520f2b09\"}}],\"defs\":[{\"type\":\"model\",\"name\":\"ReactiveHTML1\"},{\"type\":\"model\",\"name\":\"FlexBox1\",\"properties\":[{\"name\":\"align_content\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"align_items\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"flex_direction\",\"kind\":\"Any\",\"default\":\"row\"},{\"name\":\"flex_wrap\",\"kind\":\"Any\",\"default\":\"wrap\"},{\"name\":\"justify_content\",\"kind\":\"Any\",\"default\":\"flex-start\"}]},{\"type\":\"model\",\"name\":\"FloatPanel1\",\"properties\":[{\"name\":\"config\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"contained\",\"kind\":\"Any\",\"default\":true},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"right-top\"},{\"name\":\"offsetx\",\"kind\":\"Any\",\"default\":null},{\"name\":\"offsety\",\"kind\":\"Any\",\"default\":null},{\"name\":\"theme\",\"kind\":\"Any\",\"default\":\"primary\"},{\"name\":\"status\",\"kind\":\"Any\",\"default\":\"normalized\"}]},{\"type\":\"model\",\"name\":\"GridStack1\",\"properties\":[{\"name\":\"mode\",\"kind\":\"Any\",\"default\":\"warn\"},{\"name\":\"ncols\",\"kind\":\"Any\",\"default\":null},{\"name\":\"nrows\",\"kind\":\"Any\",\"default\":null},{\"name\":\"allow_resize\",\"kind\":\"Any\",\"default\":true},{\"name\":\"allow_drag\",\"kind\":\"Any\",\"default\":true},{\"name\":\"state\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"drag1\",\"properties\":[{\"name\":\"slider_width\",\"kind\":\"Any\",\"default\":5},{\"name\":\"slider_color\",\"kind\":\"Any\",\"default\":\"black\"},{\"name\":\"value\",\"kind\":\"Any\",\"default\":50}]},{\"type\":\"model\",\"name\":\"click1\",\"properties\":[{\"name\":\"terminal_output\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"debug_name\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"clears\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"toggle_value1\",\"properties\":[{\"name\":\"active_icons\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"options\",\"kind\":\"Any\",\"default\":{\"type\":\"map\",\"entries\":[[\"favorite\",\"heart\"]]}},{\"name\":\"value\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"_reactions\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"_base_url\",\"kind\":\"Any\",\"default\":\"https://tabler-icons.io/static/tabler-icons/icons/\"}]},{\"type\":\"model\",\"name\":\"copy_to_clipboard1\",\"properties\":[{\"name\":\"value\",\"kind\":\"Any\",\"default\":null},{\"name\":\"fill\",\"kind\":\"Any\",\"default\":\"none\"}]},{\"type\":\"model\",\"name\":\"FastWrapper1\",\"properties\":[{\"name\":\"object\",\"kind\":\"Any\",\"default\":null},{\"name\":\"style\",\"kind\":\"Any\",\"default\":null}]},{\"type\":\"model\",\"name\":\"NotificationAreaBase1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"NotificationArea1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"notifications\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0},{\"name\":\"types\",\"kind\":\"Any\",\"default\":[{\"type\":\"map\",\"entries\":[[\"type\",\"warning\"],[\"background\",\"#ffc107\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-exclamation-triangle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]},{\"type\":\"map\",\"entries\":[[\"type\",\"info\"],[\"background\",\"#007bff\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-info-circle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]}]}]},{\"type\":\"model\",\"name\":\"Notification\",\"properties\":[{\"name\":\"background\",\"kind\":\"Any\",\"default\":null},{\"name\":\"duration\",\"kind\":\"Any\",\"default\":3000},{\"name\":\"icon\",\"kind\":\"Any\",\"default\":null},{\"name\":\"message\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"notification_type\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_destroyed\",\"kind\":\"Any\",\"default\":false}]},{\"type\":\"model\",\"name\":\"TemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"BootstrapTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"MaterialTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]}]}};\n",
              "  var render_items = [{\"docid\":\"695a169a-ce62-4a2c-a5ea-e2cfe844999c\",\"roots\":{\"db05b70e-70bd-4901-9290-1fcbf1b561db\":\"b1aa7761-4cfe-466a-8aa1-781707e0fd3b\"},\"root_ids\":[\"db05b70e-70bd-4901-9290-1fcbf1b561db\"]}];\n",
              "  var docs = Object.values(docs_json)\n",
              "  if (!docs) {\n",
              "    return\n",
              "  }\n",
              "  const py_version = docs[0].version.replace('rc', '-rc.').replace('.dev', '-dev.')\n",
              "  const is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1\n",
              "  function embed_document(root) {\n",
              "    var Bokeh = get_bokeh(root)\n",
              "    Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
              "    for (const render_item of render_items) {\n",
              "      for (const root_id of render_item.root_ids) {\n",
              "\tconst id_el = document.getElementById(root_id)\n",
              "\tif (id_el.children.length && (id_el.children[0].className === 'bk-root')) {\n",
              "\t  const root_el = id_el.children[0]\n",
              "\t  root_el.id = root_el.id + '-rendered'\n",
              "\t}\n",
              "      }\n",
              "    }\n",
              "  }\n",
              "  function get_bokeh(root) {\n",
              "    if (root.Bokeh === undefined) {\n",
              "      return null\n",
              "    } else if (root.Bokeh.version !== py_version && !is_dev) {\n",
              "      if (root.Bokeh.versions === undefined || !root.Bokeh.versions.has(py_version)) {\n",
              "\treturn null\n",
              "      }\n",
              "      return root.Bokeh.versions.get(py_version);\n",
              "    } else if (root.Bokeh.version === py_version) {\n",
              "      return root.Bokeh\n",
              "    }\n",
              "    return null\n",
              "  }\n",
              "  function is_loaded(root) {\n",
              "    var Bokeh = get_bokeh(root)\n",
              "    return (Bokeh != null && Bokeh.Panel !== undefined)\n",
              "  }\n",
              "  if (is_loaded(root)) {\n",
              "    embed_document(root);\n",
              "  } else {\n",
              "    var attempts = 0;\n",
              "    var timer = setInterval(function(root) {\n",
              "      if (is_loaded(root)) {\n",
              "        clearInterval(timer);\n",
              "        embed_document(root);\n",
              "      } else if (document.readyState == \"complete\") {\n",
              "        attempts++;\n",
              "        if (attempts > 200) {\n",
              "          clearInterval(timer);\n",
              "\t  var Bokeh = get_bokeh(root)\n",
              "\t  if (Bokeh == null || Bokeh.Panel == null) {\n",
              "            console.warn(\"Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing\");\n",
              "\t  } else {\n",
              "\t    console.warn(\"Panel: WARNING: Attempting to render but not all required libraries could be resolved.\")\n",
              "\t    embed_document(root)\n",
              "\t  }\n",
              "        }\n",
              "      }\n",
              "    }, 25, root)\n",
              "  }\n",
              "})(window);</script>"
            ],
            "application/vnd.holoviews_exec.v0+json": "",
            "text/plain": [
              "Column\n",
              "    [0] TextInput(placeholder='Enter text here…')\n",
              "    [1] Row\n",
              "        [0] Button(name='talk')\n",
              "    [2] ParamFunction(function, _pane=Column, defer_load=False, loading_indicator=True)"
            ]
          },
          "metadata": {
            "application/vnd.holoviews_exec.v0+json": {
              "id": "db05b70e-70bd-4901-9290-1fcbf1b561db"
            }
          },
          "execution_count": 9
        }
      ],
      "source": [
        "#Creating the prompt\n",
        "#read and undertand it.\n",
        "context = [ {'role':'system', 'content':\"\"\"\n",
        "Act as an OrderBot, you work collecting orders in a delivery only fast food restaurant called\n",
        "My Dear Frankfurt. \\\n",
        "First welcome the customer, in a very friedly way, then collects the order. \\\n",
        "You wait to collect the entire order, beverages included \\\n",
        "then summarize it and check for a final \\\n",
        "time if everithing is ok or the customer wants to add anything else. \\\n",
        "Finally you collect the payment.\\\n",
        "Make sure to clarify all options, extras and sizes to uniquely \\\n",
        "identify the item from the menu.\\\n",
        "You respond in a short, very friendly style. \\\n",
        "The menu includes \\\n",
        "burguer  12.95, 10.00, 7.00 \\\n",
        "frankfurt   10.95, 9.25, 6.50 \\\n",
        "sandwich   11.95, 9.75, 6.75 \\\n",
        "fries 4.50, 3.50 \\\n",
        "salad 7.25 \\\n",
        "Toppings: \\\n",
        "extra cheese 2.00, \\\n",
        "mushrooms 1.50 \\\n",
        "martra sausage 3.00 \\\n",
        "canadian bacon 3.50 \\\n",
        "romesco sauce 1.50 \\\n",
        "peppers 1.00 \\\n",
        "Drinks: \\\n",
        "coke 3.00, 2.00, 1.00 \\\n",
        "sprite 3.00, 2.00, 1.00 \\\n",
        "vichy catalan 5.00 \\\n",
        "\"\"\"} ]\n",
        "\n",
        "#Creamos el panel.\n",
        "pn.extension()\n",
        "\n",
        "panels = []\n",
        "\n",
        "client_prompt = pn.widgets.TextInput(value=\"Hi\", placeholder='Enter text here…')\n",
        "button_conversation = pn.widgets.Button(name=\"talk\")\n",
        "\n",
        "interactive_conversation = pn.bind(add_prompts_conversation, button_conversation)\n",
        "\n",
        "dashboard = pn.Column(\n",
        "    client_prompt,\n",
        "    pn.Row(button_conversation),\n",
        "    pn.panel(interactive_conversation, loading_indicator=True),\n",
        ")\n",
        "\n",
        "dashboard"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "88db4691",
      "metadata": {
        "id": "88db4691"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.13"
    },
    "colab": {
      "provenance": [],
      "include_colab_link": true
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}